package com.kt.coroutinedemo

import android.os.Bundle
import android.os.Environment
import android.util.Log
import androidx.activity.ComponentActivity
import androidx.activity.compose.setContent
import androidx.activity.enableEdgeToEdge
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.padding
import androidx.compose.material3.Button
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.Dp
import androidx.lifecycle.MutableLiveData
import com.google.gson.Gson
import com.kt.coroutinedemo.MainActivity.Companion.defaultDownFilePath
import com.kt.coroutinedemo.MainActivity.Companion.singlePackSize
import com.kt.coroutinedemo.Netty.LinkListener
import com.kt.coroutinedemo.Netty.NettyClient
import com.kt.coroutinedemo.Netty.NettyClient.TAG
import com.kt.coroutinedemo.ui.theme.CoroutineDemoTheme
import com.kt.coroutinedemo.utils.BaseFileCommand
import com.kt.coroutinedemo.utils.DecodeUtils
import com.kt.coroutinedemo.utils.GlobalConstant
import com.kt.coroutinedemo.utils.PacketUtils
import com.streamax.app.cqbus.platform.ext.toByteArray
import com.streamax.app.cqbus.platform.socket.tcp.command.TcpCommand01
import com.streamax.app.cqbus.platform.socket.tcp.command.TcpCommand02
import com.streamax.app.cqbus.platform.socket.tcp.command.TcpCommand03
import com.streamax.app.cqbus.platform.socket.tcp.command.TcpResponse81
import com.streamax.app.cqbus.platform.socket.tcp.command.TcpResponse82
import com.swallowsonny.convertextlibrary.toHexString
import io.netty.channel.ChannelId
import kotlinx.coroutines.GlobalScope
import kotlinx.coroutines.MainScope
import kotlinx.coroutines.launch
import kotlinx.coroutines.runBlocking
import java.io.File
import java.io.FileOutputStream

class MainActivity : ComponentActivity() {
      val TAG = "MainActivity"

    companion object {
        /**
         * 单包数据大小
         */
        val singlePackSize = (1024 * 6)

        /**
         * 默认下载位置
         */
        val defaultDownFilePath =   Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS).path + "/"


    }

    val sss = MutableLiveData<Boolean>()


    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        enableEdgeToEdge()
        setContent {
            CoroutineDemoTheme {
               Column(modifier = Modifier.fillMaxSize()) {
                   Row(modifier = Modifier.fillMaxWidth()) {

                       Button(
                           onClick = { nettyClient() },
                           modifier = Modifier.padding(Dp(4F))
                       ) {
                           Text(text = "Netty连接")
                       }

                       Button(
                           onClick = { NettyClient.closeClient() },
                           modifier = Modifier.padding(Dp(4F))
                       ) {
                           Text(text = "Netty断开")
                       }

                       Button(
                           onClick = { nettySend() },
                           modifier = Modifier.padding(Dp(4F))
                       ) {
                           Text(text = "Netty发送")
                       }
                   }

                   Row(modifier = Modifier.fillMaxWidth()) {
                       Button(
                           onClick = { ConnectLocal() },
                           modifier = Modifier.padding(Dp(4F))
                       ) {
                           Text(text = "连接本地")
                       }
                       Button(
                           onClick = { getFileReadPermission() },
                           modifier = Modifier.padding(Dp(4F))
                       ) {
                           Text(text = "申请权限")
                       }
                   }
               }


            }
        }
        sss.observe(this) {

        }
    }

    /**
     * 申请读写权限
     */
    private fun getFileReadPermission() {
        requestPermissions(arrayOf(android.Manifest.permission.READ_EXTERNAL_STORAGE, android.Manifest.permission.WRITE_EXTERNAL_STORAGE), 100)
    }

    private fun ConnectLocal() {
     MainScope().launch {
         NettyClient.client(ip = "192.168.0.112", port = 8765,listener = object : LinkListener{
             override fun linkSuccess(channelId: ChannelId) {
                 Log.e(NettyClient.TAG, "linkSuccess,channelId:${channelId}")
                 //添加下载队列

             }

             override fun linkFailed() {
                 Log.e(NettyClient.TAG, "linkFailed: ", )
             }
         })

     }
    }
}

@Composable
fun Greeting(name: String, modifier: Modifier = Modifier) {
    Text(
        text = "Hello $name!",
        modifier = modifier
    )
}


//连接TCP
private fun nettyClient() {
    MainScope().launch {
       NettyClient.client("47.108.161.232",801,listener = object : LinkListener{
           override fun linkSuccess(channelId: ChannelId) {
               Log.e(TAG, "linkSuccess,channelId:${channelId}")
           }

           override fun linkFailed() {
               Log.e(TAG, "linkFailed: ", )
           }
       })

    }


}
//tcp发送
private fun nettySend(){
//    NettyClient.sendMsg( "26 26 01 00 0E 33 22 29 99 98 00 12 5A 38 31 38 00 4F 0B".hexToByteArray,needResponse = true).await()
    // 在协程作用域中使用
    GlobalScope.launch {
        try {
            //登录
            val tc01 = TcpCommand01(lineCode = "818")
            val request01 = PacketUtils.baseFilePacket(0x01, GlobalConstant.getSuNumber(), tc01.packet())
            Log.e(TAG, "TCP文件下载登录 步骤1:${request01.toHexString()}")
            // 发送请求并等待响应
            val response81 = NettyClient.sendMsg(request01, needResponse = true)?.await() ?: throw Exception("接收81指令超时!")
            Log.i(TAG, "<<<<<<<<<<<<:${response81.toHexString()} ")
            //解析81指令
            val decoded81 = BaseFileCommand(0, 0, "", 0, (0).toByteArray)
            DecodeUtils.baseEnFilePackage(response81, decoded81)
            val tcp81 = TcpResponse81().decode(decoded81.content)
            if (tcp81.result.toInt() == 0x00) {
                Log.e(
                    TAG,
                    "---------------------------TCP文件下载登录成功---------------------------"
                )
                val tc02 =
                    TcpCommand02(downloadType = 0x01, packetSize = singlePackSize, msg = "818")
                //发送下载请求
                val p2 = PacketUtils.baseFilePacket(
                    tc02.commandId.toByte(),
                    GlobalConstant.getSuNumber(),
                    tc02.packet()
                )
                Log.e(TAG, "TCP文件下载包信息请求 步骤2:${p2.toHexString()}")
                // 发送请求并等待响应
                val response82 = NettyClient.sendMsg(p2, needResponse = true)?.await()
                    ?: throw Exception("接收82指令超时!")
                Log.i(TAG, "<<<<<<<<<<<<:${response82.toHexString()} ")
                //解析82指令
                val decode82 = BaseFileCommand(0, 0, "", 0, (0).toByteArray)
                DecodeUtils.baseEnFilePackage(response82, decode82)
                val tcp82 = TcpResponse82().decode(decode82.content)
                if (tcp82.result.toInt() == 0x00) {
                    Log.e(
                        TAG,
                        "---------------------------TCP文件请求成功---------------------------"
                    )
                    Log.e(TAG, "nettySend: ${Gson().toJson(tcp82)}")
                    downloadFile(tcp82)?.let {
                        //错误信息
                        Log.e(TAG, "错误信息:${it.message}")
                    }
                }
            }

        } catch (e: Exception) {
            Log.e("Response", "等待响应时出错: ${e.message}")
        }
    }
}

/**
 * 下载文件
 */
private fun downloadFile(response82: TcpResponse82): Throwable? {
    var error: Throwable? = null
    runBlocking {
        try {
            val totalPackets = response82.mPackCount
            var currentPacketIndex = 1
            // 创建文件输出流，直接写入文件
            val file = createUniqueFile(defaultDownFilePath, response82.mFileName)
            val fileOutputStream = FileOutputStream(file)
            val token = response82.mToken
            try {
                while (currentPacketIndex <= totalPackets) {
                    // 构造请求包
                    val packet = getDownLoadPacket(token, currentPacketIndex)

                    Log.e(
                        TAG,
                        "请求文件数据包 序号:${currentPacketIndex}, 数据:${packet.toHexString()}"
                    )

                    // 发送请求并等待响应
                    val responseData = NettyClient.sendMsg(packet, needResponse = true)?.await()


                    if (responseData == null) {
                        error = Exception("未收到第${currentPacketIndex}个数据包的响应")
                        break
                    }

                    // 解析响应数据
                    val decodedPacket = BaseFileCommand(0, 0, "", 0, (0).toByteArray)
                    DecodeUtils.baseEnFilePackage(responseData, decodedPacket)

//                    // 直接写入文件，而不是存储在内存中
//                    fileOutputStream.write(decodedPacket.content)
                    currentPacketIndex++

                    Log.e(TAG, "成功接收第${currentPacketIndex}个数据包")
                }
                Log.e(TAG, "下载完成")

                if (error == null) {
                    Log.e(TAG, "文件下载完成并保存到本地")
                } else {

                }
            } finally {
                fileOutputStream.close()
            }

        } catch (e: Exception) {
            error = e
            Log.e(TAG, "下载文件时出错: ${e.message}")
            //删除文件
            val file = File(defaultDownFilePath + response82.mFileName)
            if (file.exists()) {
                file.delete()
            } else {

            }
        }
    }
    return error
}

/**
 * 创建唯一文件名，避免文件冲突
 */
private fun createUniqueFile(directoryPath: String, fileName: String): File {
    val directory = File(directoryPath)

    // 确保目录存在
    if (!directory.exists()) {
        if (!directory.mkdirs()) {
            Log.w(TAG, "无法创建目录: $directoryPath")
        } else {
            Log.d(TAG, "成功创建目录: $directoryPath")
        }
    }

    var file = File(directory, fileName)
    var counter = 1
    val fileNameWithoutExtension = fileName.substringBeforeLast(".", fileName)
    val extension = fileName.substringAfterLast(".", "")

    // 循环检查文件是否存在，最多尝试1000次
    while (file.exists() && counter <= 1000) {
        val newFileName = if (extension.isNotEmpty()) {
            "${fileNameWithoutExtension}_$counter.$extension"
        } else {
            "${fileNameWithoutExtension}_$counter"
        }
        file = File(directory, newFileName)
        counter++
    }

    // 如果尝试了1000次仍然存在，使用时间戳
    if (file.exists()) {
        val timestamp = System.currentTimeMillis()
        val newFileName = if (extension.isNotEmpty()) {
            "${fileNameWithoutExtension}_${timestamp}.$extension"
        } else {
            "${fileNameWithoutExtension}_${timestamp}"
        }
        file = File(directory, newFileName)
    }

    Log.d(TAG, "最终文件路径: ${file.absolutePath}")
    return file
}


/**
 * 获取下载包指令
 */
private fun getDownLoadPacket(mToken: Int, packetSn: Int): ByteArray {
    val com03 = TcpCommand03(mToken, packetSn)
    return PacketUtils.baseFilePacket(0x03, GlobalConstant.getSuNumber(), com03.packet())
}

@Preview(showBackground = true)
@Composable
fun GreetingPreview() {
    CoroutineDemoTheme {
        Greeting("Android")
    }
}